<template>
  <div class="container" v-loading="loading">
    <div class="other-content2" v-show="rightShow">
      <button class="save-button" @click="saveImage">
        {{ $t("保存图片") }}
      </button>
      <button class="update-button" @click="updateF5">
        {{ $t("刷新") }}
      </button>
    </div>

    <div class="other-content" v-show="isShow">
      <button class="floating-button" @click="goBack">{{ $t("返回") }}</button>
    </div>

    <div
      class="chart"
      ref="chartContainer"
      :style="{ width: width, height: height }"
    ></div>
    <YAxisConfig ref="yContainer" @confirm="yOnConfirm"></YAxisConfig>
  </div>
</template>

<script setup>
import { ref, watchEffect, getCurrentInstance, onUnmounted } from "vue";

import * as echarts from "echarts";
import moment from "moment";
import router, { state } from "../router";
import YAxisConfig from "./YAxisConfig.vue";
import * as utils from "../utils/utils";
import { Loading } from "element-plus/es/components/loading/src/service";

const props = defineProps({
  width: {
    type: String,
    default: "100%",
  },
  height: {
    type: String,
    default: "100%",
  },
  isRt: {
    type: Boolean,
    default: true,
  },
});

const isShow = ref(false);
const rightShow = ref(true);
const loading = ref(true);
const chatOption = ref({});

const instance = getCurrentInstance();
const $axios = instance.proxy.$axios;
const $message = instance.proxy.$message;
const $t = instance.proxy.$t;

let chart;
let timer;
let fields = []; //表内所有的字段名
let groups = []; //用户的权限组 Administrator
const chartContainer = ref(null);
const yContainer = ref(null);

function goBack() {
  console.log("goBack");
  router.go(-1);
}

// const { $refs } = getCurrentInstance();
// $refs.yContainer.showDialog()

//根据opt的曲线显示隐藏状态，计算Y轴显示隐藏和偏移配置
function initYAxisConfig(option) {
  //覆盖slected
  let jsonString = localStorage.getItem(
    `${state.params.curve_name}_${state.lang}_selected`
  );
  if (jsonString != undefined) {
    let jsonData = JSON.parse(jsonString);
    option["legend"]["selected"] = jsonData;

    option["yAxis"].forEach((y) => {
      if (y["y_show"] == 0) {
        y["show"] = false;
      } else {
        let hasTrue = false;
        for (const v of y["curve_names"]) {
          if (jsonData[v]) {
            hasTrue = true;
            break;
          }
        }
        y["show"] = hasTrue;
      }
    });
  }
  updateYOffset(option);
}

// function updateYAuto(yAxis) {
//   yAxis.forEach((y) => {
//     y = utils.y_auto_function(y);
//   });
// }

function initTextStyle(option) {
  let textStyle = {
    fontSize: state.fontsize,
    fontFamily: "yahei",
  };
  option.legend["textStyle"] = textStyle;
  option.grid[0]["top"] = parseInt(state.fontsize) + 40;
}

/**
 * 函数整体逻辑
定义了一个比较两个数组是否相同的函数。
尝试从本地存储中获取之前保存的 y 轴配置数据。
如果获取到了数据并且与当前配置数据相同，则用本地存储的数据更新当前配置。
如果数据不同，则从本地存储中删除之前保存的数据
 */
function initYMaxMinAutoConfig(option) {
  function compareArrays(array1, array2) {
    if (array1.length !== array2.length) {
      //   console.log("两个数组的长度不同");
      return false;
    }

    for (let i = 0; i < array1.length; i++) {
      const obj1 = array1[i];
      const obj2 = array2.find((obj) => obj.name === obj1.name);
      if (!obj2) {
        console.log("两个数组中存在不同的对象");
        return false;
      }
    }

    console.log("两个数组相同");
    return true;
  }
  //覆盖slected
  let jsonString = localStorage.getItem(
    `${state.params.curve_name}_${state.lang}_yAxis`
  );
  if (jsonString != undefined) {
    let jsonData = JSON.parse(jsonString);
    if (compareArrays(option["yAxis"], jsonData)) {
      let yIndex = 0;
      option["yAxis"].forEach((y) => {
        y["min"] = jsonData[yIndex]["min"];
        y["max"] = jsonData[yIndex]["max"];
        y["_min"] = jsonData[yIndex]["_min"];
        y["_max"] = jsonData[yIndex]["_max"];
        y["_auto"] = jsonData[yIndex]["_auto"];
        yIndex += 1;
      });
    } else {
      localStorage.removeItem(`${state.params.curve_name}_${state.lang}_yAxis`);
    }
  }
}

/**
 *  yAxis 进行排序并更新 series 中的 yAxisIndex
 */
function sortAndUpdateYAxis(option, compareFn) {
  const originalYAxis = [...option.yAxis];
  const indexMap = new Map();
  option.yAxis.sort(compareFn).forEach((sortedYAxis, newIndex) => {
    const originalIndex = originalYAxis.indexOf(sortedYAxis);
    indexMap.set(originalIndex, newIndex);
  });
  option.series.forEach((series) => {
    series.yAxisIndex = indexMap.get(series.yAxisIndex);
  });
}

function updateYOffset(option) {
  //重新计算offset
  const y_offset = option["other"]["y_offset"];
  let leftCount = 0;
  let rightCount = 0;
  let leftOffset = -1;
  let rightOffset = -1;
  let baseRightOffset = 80; // 保存,刷新,返回,偏移量

  sortAndUpdateYAxis(option, (a, b) => Math.abs(a.Order) - Math.abs(b.Order));

  option["yAxis"].forEach((y) => {
    if (y["position"] == "left") {
      y["nameTextStyle"] = {
        align: "right",
      };
      y["offset"] = leftCount * y_offset;
      if (y["show"] && y["y_show"]) {
        leftCount += 1;
        leftOffset = y["offset"] > leftOffset ? y["offset"] : leftOffset;

        // 显示Y轴时恢复完整状态
        if (y["_savedState"]) {
          // 恢复保存的状态
          y["min"] = y["_savedState"]["min"];
          y["max"] = y["_savedState"]["max"];
          y["_min"] = y["_savedState"]["_min"];
          y["_max"] = y["_savedState"]["_max"];
          y["_auto"] = y["_savedState"]["_auto"];
          // 清除保存的状态
          delete y["_savedState"];
        } else if (y["y_min"] !== undefined && y["y_max"] !== undefined) {
          // 兼容原有逻辑
          y["min"] = y["y_min"];
          y["max"] = y["y_max"];
          delete y["y_min"];
          delete y["y_max"];
        }
      } else {
        // 隐藏Y轴时保存完整状态
        if (!y["_savedState"]) {
          y["_savedState"] = {
            min: y["min"],
            max: y["max"],
            _min: y["_min"],
            _max: y["_max"],
            _auto: y["_auto"],
          };
        }

        y["offset"] = -y_offset;
        y["min"] = null;
        y["max"] = null;
      }
    } else if (y["position"] == "right") {
      y["nameTextStyle"] = {
        align: "left",
      };
      y["offset"] = rightCount * y_offset;
      if (y["show"] && y["y_show"]) {
        rightCount += 1;
        rightOffset = y["offset"] > rightOffset ? y["offset"] : rightOffset;

        // 显示Y轴时恢复完整状态
        if (y["_savedState"]) {
          // 恢复保存的状态
          y["min"] = y["_savedState"]["min"];
          y["max"] = y["_savedState"]["max"];
          y["_min"] = y["_savedState"]["_min"];
          y["_max"] = y["_savedState"]["_max"];
          y["_auto"] = y["_savedState"]["_auto"];
          // 清除保存的状态
          delete y["_savedState"];
        } else if (y["y_min"] !== undefined && y["y_max"] !== undefined) {
          // 兼容原有逻辑
          y["min"] = y["y_min"];
          y["max"] = y["y_max"];
          delete y["y_min"];
          delete y["y_max"];
        }
      } else {
        // 隐藏Y轴时保存完整状态
        if (!y["_savedState"]) {
          y["_savedState"] = {
            min: y["min"],
            max: y["max"],
            _min: y["_min"],
            _max: y["_max"],
            _auto: y["_auto"],
          };
        }

        y["offset"] = -y_offset;
        y["min"] = null;
        y["max"] = null;
      }
    }
  });

  let grid_left = leftOffset + option["other"]["y_offset"] * 1.5;
  option["grid"][0]["left"] = grid_left;
  option["legend"]["left"] = grid_left + 10;

  let grid_right = rightOffset + option["other"]["y_offset"] * 1.5;
  if (state.params.curve_name != "prt") {
    option["grid"][0]["right"] = grid_right + baseRightOffset;
    let legendWidth =
      chartContainer.value.offsetWidth -
      grid_left -
      grid_right -
      baseRightOffset;
    option["legend"]["width"] = legendWidth;
  } else {
    option["grid"][0]["right"] = grid_right;
    let legendWidth = chartContainer.value.offsetWidth - grid_left - grid_right;
    option["legend"]["width"] = legendWidth;
    option["grid"][0]["bottom"] = 50;
  }
}

function updateYAxisConfig(name, selected) {
  let option = chart.getOption();
  //设置Y轴的显示隐藏
  option["yAxis"].forEach((y) => {
    if (y["y_show"] == 0) {
      y["show"] = false;
    } else {
      let hasFound = y["curve_names"].indexOf(name) !== -1;
      if (hasFound) {
        let hasTrue = false;
        for (const v of y["curve_names"]) {
          if (selected[v]) {
            hasTrue = true;
            break;
          }
        }
        y["show"] = hasTrue;
      }
    }
  });
  updateYOffset(option);

  // 直接使用更新后的 option
  chart.setOption(option);
}

const initChart = async () => {
  chart = echarts.init(chartContainer.value);
  let option = {};
  console.log(state);
  // 异步请求后台数据
  const response = await $axios.get("/curve/option", {
    params: {
      db: state.db,
      tbid: state.tbid,
      ymode: state.ymode,
      lang: state.lang,
      offset: state.offset,
      curve_name: state.params.curve_name,
      fields: state.query.fields || "",
      groups: state.query.groups || "",
    },
    timeout: 9000,
  });
  option = response.data;
  fields = option["legend"]["fields"].join(",");

  //   console.log(state.params.curve_name);
  isShow.value = state.params.curve_name == "his";
  rightShow.value = state.params.curve_name != "prt";
  let ary = ["his", "prt", "rt"];
  if (ary.includes(state.params.curve_name)) {
    // 获取当前时间并格式化为 yyyy-mm-dd hh:mm:ss
    var end_time = moment().format("YYYY-MM-DD HH:mm:ss");

    // 获取当前时间减去3小时的时间并格式化为 yyyy-mm-dd hh:mm:ss
    var start_time = moment()
      .subtract(state.last, "hour")
      .format("YYYY-MM-DD HH:mm:ss");
    // if (state.query.start_time != undefined){
    start_time = state.query.start_time;
    end_time = state.query.end_time;
    // }
    try {
      const { data } = await $axios.post(
        "/curve/query",
        {
          start_time: start_time,
          end_time: end_time,
          batch: state.query.batch,
          table_name: "Data" + state.tbid,
          db: state.db,
          fields,
          lang: state.lang,
          freq: state.freq,
          last: state.last,
        },
        { timeout: 9000 }
      );
      option = utils.mergeJSON(option, data);
    } catch (error) {
      loading.value = false;
      if (error.code === "ECONNABORTED") {
        console.log("Request timed out!");
      } else {
        // 如果错误不是由超时引起的，你也许想要处理其他类型的错误
        console.log("An error occurred:", error.message);
      }
    }
    // option = Object.assign({},option,data)
  }

  // 初始化echarts实例
  const myOption = {
    tooltip: {
      trigger: "axis",
      axisPointer: {
        type: "cross",
        animation: false,
        z: 0,
        label: {
          //   show: false,
          //   width: 200,
          //   overflow: "break",
          //   backgroundColor: "#505765",
          margin: 0,
          fontSize: 11,
          //   padding: [5, 1, 5, 1],
          //   formatter: label_formatter,
        },
      },
      textStyle: {
        fontSize: 20,
        fontFamily: "yahei",
      },
    },

    graphic: [
      {
        // 添加 graphic 元素
        type: "text",
        left: 5, // 文本位置
        top: 5, // 顶部留出一些空间显示文本
        style: {
          text: "", // 显示的批号文本
          textAlign: "center",
          fill: "#000000", // 文本颜色
          fontSize: 10,
        },
      },
    ],
    xAxis: {
      type: "time",
      boundaryGap: ["20%", "20%"],
      // axisTick: {
      //   show: false,
      //   length: 0,
      // },
      // type: "category",

      // boundaryGap:false,

      data: [],

      nameTextStyle: {
        fontFamily: "yahei",
        fontSize: 20,
      },
    },
    legend: {
      width: "90%",

      top: 8,
      data: [
        // window.vue.$t("速度"),
        // window.vue.$t("体积"),
        // window.vue.$t("杯腔压力"),
        // window.vue.$t("管路压力"),
      ],
      selected: {},
      // selected: {

      //     '速度': true,

      //     window.vue.$t('体积'): true,

      //     window.vue.$t('杯腔压力'): true,

      //     window.vue.$t('管路压力'): true

      // },

      //   type: "scroll",

      //orient: 'vertical',

      icon: "circle",

      //right: 2,

      //top: 20,

      //bottom: 2,

      //itemGap: 10,

      //itemWidth: 64,

      //itemHeight: 32,

      //pageIconSize: 25,

      textStyle: {
        fontSize: 16,
        fontFamily: "yahei",
      },
      type: "scroll", // 启用图例的滚动类型
      pageButtonItemGap: 5,
      pageButtonGap: 10,
      pageButtonPosition: "end",
      pageIconColor: "#2f4554",
      pageIconSize: 25,
      pageIconInactiveColor: "#aaa",
      pageTextStyle: {
        color: "#333",
      },
    },

    grid: [
      {
        // grid.left grid.right grid.top grid.bottom
        left: "3%",
        right: "30%",
        top: 80,
        // bottom:0,
        //left: '10%',
        //   width: "auto",
        //   height: "auto",
        //right: '18%',

        bottom: "100",

        // containLabel: true,
      },
    ],
    toolbox: {
      show: true,
      feature: {
        myButton: {
          show: false,
          title: $t("保存图片"),
          // icon: "path://M0,0 L10,0 L5,10 Z",
          icon: "path://M160 652.224l238.336-119.168 135.04 330.944H576v64H192A96 96 0 0 1 96 832V192A96 96 0 0 1 192 96h640A96 96 0 0 1 928 192v384h-64V192a32 32 0 0 0-32-32H192a32 32 0 0 0-32 32v460.224z m0 71.552V832a32 32 0 0 0 32 32h273.28L369.664 618.88 160 723.84z m640 94.976l73.344-73.408 45.312 45.312L768 941.248l-150.656-150.592 45.312-45.312 73.344 73.408V576h64v242.752zM640 416a96 96 0 1 1 0-192 96 96 0 0 1 0 192z m0-64a32 32 0 1 0 0-64 32 32 0 0 0 0 64z",

          onclick: () => {
            saveImage();
            console.log("My Button clicked");
          },
        },
      },
    },
    dataZoom: [
      {
        type: "slider",
        bottom: 30,

        handleIcon:
          "path://M10.7,11.9H9.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4h1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7v-1.2h6.6z M13.3,22H6.7v-1.2h6.6z M13.3,19.6H6.7v-1.2h6.6z", // jshint ignore:line

        handleSize: 20,

        moveHandleSize: 20,

        handleStyle: {
          shadowBlur: 6,

          shadowOffsetX: 1,

          shadowOffsetY: 2,

          shadowColor: "# aaa ",
        },
        show: true,
        realtime: false,
        start:
          localStorage.getItem(
            `${state.params.curve_name}_${state.lang}_dataZoomStart`
          ) || 0,
        end:
          localStorage.getItem(
            `${state.params.curve_name}_${state.lang}_dataZoomEnd`
          ) || 100,
      },
      {
        type: "inside",
        bottom: 30,
        realtime: false,
        start:
          localStorage.getItem(
            `${state.params.curve_name}_${state.lang}_dataZoomStart`
          ) || 0,
        end:
          localStorage.getItem(
            `${state.params.curve_name}_${state.lang}_dataZoomEnd`
          ) || 100,
      },
    ],
  };
  if (state.params.curve_name == "prt") {
    delete myOption["dataZoom"];
    delete myOption["toolbox"];
    delete myOption["legend"]["type"];
  }
  //   let opt = Object.assign({}, myOption, option); //浅拷贝，myOption一些值不一定被保留
  let opt = utils.mergeJSON(myOption, option);
  //   opt.legend["width"] = 950; //配合offset45
  // 枚举到文本的映射
  const rcpTypeToText = {
    0: "[]",
    1: "PBMC",
    2: "SPIN",
    3: "BEADWASH",
    4: "DILUTION",
    5: "CULTUREWASH",
  };
  if (typeof state.query.batch !== "undefined") {
    opt.graphic[0].style.text = state.query.batch || opt.graphic[0].style.text;
  }
  if (typeof state.query.rcp_type !== "undefined") {
    opt.graphic[0].style.text += " " + rcpTypeToText[state.query.rcp_type];
  }

  // 在合并选项后对数据进行处理
  try {
    utils.processTimeData(opt, state.lang);
  } catch (error) {
    console.error("处理时间格式时出错:", error);
  }

  initYAxisConfig(opt);
  initYMaxMinAutoConfig(opt);

  //强制Y轴自适应
  if (state.y_auto != 0) {
    opt["yAxis"].forEach((y) => {
      y["min"] = null;
      y["max"] = null;
    });
  }
  initTextStyle(opt);
  //   console.log(opt);
  fields = opt["legend"]["fields"].join(",");

  chart.setOption(opt);

  chart.on("datazoom", ({ start, end }) => {
    localStorage.setItem(
      `${state.params.curve_name}_${state.lang}_dataZoomStart`,
      start
    );
    localStorage.setItem(
      `${state.params.curve_name}_${state.lang}_dataZoomEnd`,
      end
    );
  });

  chart.on("legendselectchanged", (params) => {
    const name = params.name;
    const selected = params.selected;
    updateYAxisConfig(name, selected);
    console.log(
      `${state.params.curve_name}_${state.lang}_selected`,
      JSON.stringify(selected)
    );
    //保存selected
    localStorage.setItem(
      `${state.params.curve_name}_${state.lang}_selected`,
      JSON.stringify(selected)
    );

    // console.log(chart.getOption());
  });

  chart.on("click", (params) => {
    if (params.componentType === "yAxis") {
      if (state.query.groups) {
        if (state.y_click != 0) {
          const yAxisIndex = params.yAxisIndex;
          let yAxis = chart.getOption()["yAxis"];
          yContainer.value.showDialog(yAxis, yAxisIndex);
        }
      }
    }
  });
  if (state.params.curve_name == "rt" && state.last == 0) {
    //   updateChart();
    timer = setInterval(() => {
      updateChart();
    }, state.freq * 1000);
  }
  loading.value = false;

  setTimeout(() => {
    document.title = "Example";
    // var newElement = document.createElement("p");
    // newElement.textContent = "Hello from JavaScript!";
    // document.body.appendChild(newElement);
    // document.readyState = "complete";
  }, 1000);
};

const updateChart = async () => {
  // 获取当前时间并格式化为 yyyy-mm-dd hh:mm:ss
  const end_time = moment().format("YYYY-MM-DD HH:mm:ss");

  // 获取当前时间减去3小时的时间并格式化为 yyyy-mm-dd hh:mm:ss
  const start_time = moment()
    .subtract(state.last, "hour")
    .format("YYYY-MM-DD HH:mm:ss");
  try {
    // 异步请求后台数据
    const { data } = await $axios.post(
      "/curve/query",
      {
        start_time: start_time,
        end_time: end_time,
        batch: state.query.batch,
        table_name: "Data" + state.tbid,
        db: state.db,
        fields,
        lang: state.lang,
        freq: state.freq,
        last: state.last,
      },
      { timeout: 30000 }
    );
    chart.setOption(data);
  } catch (error) {
    loading.value = false;
  }
};

// chart.on("ready", function () {
//   console.log("图表初始化完成！");
//   // 在 ready 事件中设置图表数据
//    initChart();
// });

watchEffect(() => {
  //   console.log("watchEffect 正在监视。。。");
  if (chartContainer.value) {
    state.freq = 1;
    initChart();
  }
});

onUnmounted(() => {
  chart.dispose();
  clearInterval(timer);
});

function getTimeRange() {
  const option = chart.getOption();
  // 如果使用了 time 组件定义了时间轴，可以从其中获取时间范围的值
  const ary = option.xAxis[0].data;
  const regex = /[:\s\n]/g;
  const start_time = ary[0].replace(regex, "_");
  const end_time = ary[ary.length - 1].replace(regex, "_");
  return {
    start_time,
    end_time,
  };
}

const updateF5 = async () => {
  location.reload();
};
const saveImage = async () => {
  try {
    loading.value = true;
    const imgData = chart.getDataURL();

    var range = getTimeRange();
    let data = {
      data: imgData,
      curve_name: state.params.curve_name,
      ...range,
    };
    if (state.query.batch != undefined) {
      data["batch"] = state.query.batch;
      data[
        "file_name"
      ] = `${state.params.curve_name}curve_${range.start_time}_${range.end_time}_${state.query.batch}.png`;
    } else {
      data[
        "file_name"
      ] = `${state.params.curve_name}curve_${range.start_time}_${range.end_time}.png`;
    }

    const response = await $axios.post("/curve/saveimage", data);
    loading.value = false;
    $message({
      message: $t("保存成功"),
      type: "success",
    });
    console.log("Image saved:", response.data);
  } catch (error) {
    loading.value = false;
    console.error("Failed to save image:", error);
  }
};

function yOnConfirm(yAxis) {
  //   updateYAuto(yAxis);
  chart.setOption({ yAxis });
  localStorage.setItem(
    `${state.params.curve_name}_${state.lang}_yAxis`,
    JSON.stringify(yAxis)
  );
}

function label_formatter(params) {
  if (params.axisDimension == "y" && params.axisIndex >= 0) {
    if (chart.getOption().yAxis[params.axisIndex].show) {
      //   console.log(chart.getOption());
      return params.value.toFixed(1);
    }
  }
  return "";
}
</script>


<style scoped>
.my-icon {
  background-image: url("/assets/return.png");
}

.container {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
}

.chart-wrapper {
  flex: 1;
  position: relative;
  height: 0;
  overflow: hidden;
}

.chart {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

.other-content {
  position: relative;
  width: 100%;
  height: 100vh;
}

.other-content2 {
  position: relative;
  width: 100%;
  height: 100vh;
}

.update-button {
  position: fixed;
  right: 20px;
  top: 80px;
  padding: 10px;
  z-index: 999;
}
.save-button {
  position: fixed;
  right: 20px;
  top: 20px;
  padding: 10px;
  z-index: 999;
}

.floating-button {
  position: fixed;
  right: 20px;
  top: 140px; /* 这里调整了 top 的值 */
  padding: 10px;
  z-index: 999;
}
</style>